﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Data.Entity;
using System.Data.Entity.ModelConfiguration.Conventions;
using System.Data.Entity.Migrations;
using System.Data.Entity.Infrastructure;
using System.Data.SqlClient;
using RooHui.Tool;
using RooHui.Infrastructure.Entities.Repository;

namespace RooHui.Infrastructure.Entities.EFContext
{
    public class Context : DbContext
    {
        static string conString = System.Configuration.ConfigurationManager.ConnectionStrings["Context"].ConnectionString;
        public Context()
            :base("name=Context")
        {
            Database.SetInitializer<Context>(null);
        }

        public DbSet<P_AmountHistory> AmountHistory { get; set; }
        public DbSet<P_AmountOperation> AmountOperation { get; set; }
        public DbSet<P_Enterprise> Enterprise { get; set; }
        public DbSet<P_GuaranteeCompany> GuaranteeCompany { get; set; }
        public DbSet<P_Investment> Investment { get; set; }
        public DbSet<P_Member> Member { get; set; }
        public DbSet<P_MemberLog> MemberLog { get; set; }
        public DbSet<P_Order> Order { get; set; }
        public DbSet<P_PayBack> PayBack { get; set; }
        public DbSet<P_PayBackItem> PayBackItem { get; set; }
        public DbSet<P_Policy> Policy { get; set; }
        public DbSet<P_ProcessDoing> ProcessDoing { get; set; }
        public DbSet<P_ProcessStepDoing> ProcessStepDoing { get; set; }
        public DbSet<P_ProcessDoingHistory> ProcessDoingHistory { get; set; }
        public DbSet<P_ProcessStep> ProcessStep { get; set; }
        public DbSet<P_Product> Product { get; set; }
        public DbSet<P_Project> Project { get; set; }
        public DbSet<P_ProjectHistory> ProjectHistory { get; set; }
        public DbSet<P_ProjectPolicy> ProjectPolicy { get; set; }
        public DbSet<P_PromotionPolicy> PromotionPolicy { get; set; }
        public DbSet<P_RepaymentPlan> RepaymentPlan { get; set; }
        public DbSet<P_RepaymentPlanItem> RepaymentPlanItem { get; set; }
        public DbSet<P_Resource> Resource { get; set; }
        public DbSet<S_Configration> Configration { get; set; }
        public DbSet<S_SystemLog> SystemLog { get; set; }
        public DbSet<U_Account> Account { get; set; }
        public DbSet<U_Module> Module { get; set; }
        public DbSet<U_Role> Role { get; set; }
        public DbSet<U_RoleModule> RoleModule { get; set; }
        public DbSet<U_Secret> Secret { get; set; }
        public DbSet<U_User> User { get; set; }
        public DbSet<U_UserRole> UserRole { get; set; }
        public DbSet<P_Process> Process { get; set; }
        public DbSet<P_ProcessDef> ProcessDef { get; set; }
        public DbSet<P_CheckCodeStream> CheckCodeStream { get; set; }
        public DbSet<P_AgentInfo> AgentInfo { get; set; }
        public DbSet<P_AgentProfitStream> AgentProfitStream { get; set; }
        public DbSet<P_Province> Province { get; set; }
        public DbSet<P_City> City { get; set; }
        public DbSet<P_County> County { get; set; }
        public DbSet<P_OrderPolicy> OrderPolicy { get; set; }
        public DbSet<P_Information> Information { get; set; }

        protected override void OnModelCreating(DbModelBuilder modelBuilder)
        {
            modelBuilder.Conventions.Remove<PluralizingTableNameConvention>();//移除复数表名的契约
        }

        /// <summary>
        /// 执行一个存储过程，返回影响的行数
        /// </summary>
        /// <param name="procedureName"></param>
        /// <param name="parms"></param>
        /// <returns></returns>
        public static int ExcuteProcedure(string procedureName, params SqlParameter[] parms)
        {
            using (SqlConnection con = new SqlConnection(conString))
            {
                try
                {
                    SqlCommand com = con.CreateCommand();
                    com.CommandType = System.Data.CommandType.StoredProcedure;
                    com.CommandText = procedureName;
                    foreach (var item in parms)
                    {
                        com.Parameters.Add(item);
                    }
                    return com.ExecuteNonQuery();
                }
                catch (Exception e)
                {
                    LogHelper.Write(CommonLogger.Application, e);
                }
            }
            return 0;
        }
        /// <summary>
        /// 执行一个存储过程，返回执行结果
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="procedureName"></param>
        /// <param name="packageAction"></param>
        /// <param name="parms"></param>
        /// <returns></returns>
        public static T ExcuteProcedure<T>(string procedureName, Func<SqlDataReader, T> packageAction, params SqlParameter[] parms)
        {
            using (SqlConnection con = new SqlConnection(conString))
            {
                SqlCommand com = con.CreateCommand();
                com.CommandType = System.Data.CommandType.StoredProcedure;
                com.CommandText = procedureName;
                foreach (var item in parms)
                {
                    com.Parameters.Add(item);
                }
                con.Open();
                SqlDataReader dr = com.ExecuteReader();
                try
                {
                    T t = packageAction(dr);
                    dr.Close();
                    return t;
                }
                catch (Exception e)
                {
                    LogHelper.Write(CommonLogger.Application, e);
                    dr.Close();
                }
            }
            return default(T);
        }

        public static void AsyncExcuteNonQuery(string sqlStr, Action<int> callback, params SqlParameter[] parms)
        {
            SqlConnection con = new SqlConnection(conString);
            SqlCommand com = con.CreateCommand();
            com.CommandType = System.Data.CommandType.Text;
            com.CommandText = sqlStr;
            foreach (var item in parms)
            {
                com.Parameters.Add(item);
            }
            con.Open();
            try
            {
                com.BeginExecuteNonQuery(result =>
                {
                    SqlCommand command = (SqlCommand)result.AsyncState;
                    try
                    {
                        int affect = command.EndExecuteNonQuery(result);
                        if (callback != null)
                        {
                            callback.Invoke(affect);
                        }
                        SqlConnection connection = command.Connection;
                        if (connection.State == System.Data.ConnectionState.Open)
                        {
                            connection.Close();
                        }
                    }
                    catch (Exception e)
                    {
                        LogHelper.Write(CommonLogger.Application, LogLevel.Error, e);
                    }
                    finally
                    {
                        if (command != null)
                        {
                            SqlConnection connection = command.Connection;
                            if (connection.State == System.Data.ConnectionState.Open)
                            {
                                connection.Close();
                            }
                        }
                        else
                        {
                            LogHelper.Write(CommonLogger.Application, LogLevel.Error, "异步执行callback result == null，将导致connection无法关闭。");
                        }
                    }
                }, com);
            }
            catch (Exception e)
            {
                LogHelper.Write(CommonLogger.Application, LogLevel.Error, e);
                if (con.State == System.Data.ConnectionState.Open)
                {
                    con.Close();
                }
            }
        }
    }
}
